home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Utilities Experience
/
The Utilities Experience - Volume 1.iso
/
software
/
emulation
/
frodo
/
src
/
6569.asm
< prev
next >
Wrap
Assembly Source File
|
1996-01-29
|
56KB
|
2,899 lines
*
* 6569.asm - VIC-Emulation
*
* Copyright (C) 1994-1996 by Christian Bauer
*
*
* Anmerkungen:
* ------------
*
* Funktionsweise/Periodic:
* - Die VIC-Emulation arbeitet zeilenweise. Pro (simulierter)
* C64-Rasterzeile wird vom 6510-Task die Routine Periodic6569
* aufgerufen, die eine Pixelzeile der Grafik anhand der aktuellen
* Einstellungen in den VIC-Registern aufbaut. Dadurch können
* Rastereffekte sehr gut emuliert werden.
* - Die Emulation schreibt die Grafikdaten für eine Rasterzeile in einen
* 8-Bit-Chunky-Puffer, der in jeder Rasterzeile in die Anzeige kopiert
* wird. Bei 4 Bit werden die Daten für ein ganzes Bild in den Puffer
* kopiert, der dann im VIC-VBlank konvertiert wird.
* - Die Auswahl der 5 verschiedenen Darstellungsmodi (plus 3 ungültige,
* die einen schwarzen Bildschirm erzeugen) geschieht über den
* Zeiger DisplayProc, der auf die entsprechende Routine (z.B. TextStd,
* BitMapMulti etc.) zeigt und der bei einem Schreibzugriff auf eines
* der beiden Kontrollregister CTRL1/CTRL2 neu gesetzt wird
*
* 6510-Zyklenzähler
* - In jeder Rasterzeile wird der Zyklenzähler für die CPU neu gesetzt,
* und zwar unterschiedlich je nachdem, ob eine Bad Line stattfand
* oder nicht
* - Für jedes dargestellte Sprite werden nochmal je 2 Zyklen abgezogen
*
* Bad Lines:
* - Eine Bad Line ist dann, wenn $30 <= RASTER <= $f7 und
* die unteren drei Bits von RASTER mit den unteren drei Bits von
* Reg. $11 (Y-Scroll) übereinstimmen
* - In einer Bad Line werden 40 Bytes aus Videomatrix und Farb-RAM geholt
*
* Rasterzähler RC/Grafikdarstellung:
* - Der RC wird in jeder Bad Line auf Null gesetzt, gleichzeitig wird
* die Darstellung der Grafik angeschaltet (DISPLAYOFF wird gelöscht)
* - Am Ende einer Rasterzeile wird der RC um 1 erhöht, es sei denn,
* er steht auf 7. In diesem Fall wird die Darstellung ausgeschaltet.
* - Ist DISPLAYOFF gesetzt, wird in der Textspalte $3fff dargestellt,
* ansonsten Text oder Bitmapgrafik
* - Deshalb wird im oberen/unteren Rahmen immer $3fff dargestellt, weil
* es dort keine Bad Lines gibt und der RC nie zurückgesetzt wird
*
* Videomatrixzähler VC:
* - Es gibt zwei Register, VCBASE und VCCOUNT. Zum Zugriff auf die
* Grafikdaten wird VCCOUNT benutzt.
* - Beim VBlank wird VCBASE auf Null gesetzt
* - Zu Beginn jeder Zeile wird VCCOUNT mit dem Wert aus VCBASE geladen
* - Wenn DISPLAYOFF gelöscht ist und Grafik dargestellt wird, wird
* VCCOUNT um 40 erhöht (symbolisch für die 40 Zugriffe des VIC)
* - Wenn die Darstellung abgeschaltet wird, weil RC=7 ist (am Ende
* einer Zeile) wird VCBASE mit dem Wert aus VCCOUNT geladen
*
* Spritedatenzähler MCx/Spritedarstellung:
* - Da die Spritedaten beim VIC am Ende einer Rasterzeile geholt werden
* und daher die Y-Positionen der Sprites eins niedriger als die
* Rasterzeilennummern sind, werden die Spritedatenzähler in der
* Emulation am Ende einer Rasterzeile gehandhabt (nachdem die Sprites
* gezeichnet wurden)
* - Wenn ein Sprite eingeschaltet ist und die Y-Koordinate gleich den
* unteren 8 Bit von RASTER ist, wird der Datenzähler auf Null gesetzt
* und die Darstellung des Sprite eingeschaltet (Bit in SPRITEON).
* Jede folgende Rasterzeile wird der Zähler um 3 erhöht, solange er
* kleiner als 60 ist. Erreicht er 60, wird die Darstellung des Sprite
* ausgeschaltet. Wenn das Sprite Y-expandiert ist, wird der Zähler nur
* in den Zeilen erhöht, in denen die unteren Bits von Y-Koordinate und
* Zeilennummer gleich sind.
* - Der Puffer GfxCollBuf wird beim Malen der Grafikdaten mit Flags
* gefüllt, ob das zugehörige Pixel ein Vorder- oder Hintergrundpixel
* ist. Dieser Puffer wird für die Sprite-Grafik-Kollisionserkennung
* und für das Zeichnen von Hintergrundsprites benutzt.
*
* X-Scroll>0 und 40 Spalten:
* - Wenn der X-Scroll>0 und die 40-Spalten-Darstellung eingeschaltet
* ist, hängt das, was am linken Bildrand dargestellt wird, vom
* aktuellen Grafikmodus ab
* - Im Standard-Text-, Multicolor-Text- und Multicolor-Bitmap-Modus wird
* dort die Hintergrundfarbe aus Reg.$21 dargestellt
* - Im Standard-Bitmap- und ECM-Text-Modus wird die Hintergrundfarbe
* der letzten 8 Pixel der vorherigen Zeile dargestellt
*
* Inkompatibilitäten:
* - Effekte, die durch die Änderung von VIC-Registern innerhalb einer
* Rasterzeile erreicht werden, können nicht emuliert werden
* - Sprite-Kollisionen werden nur innerhalb des sichtbaren Bereiches
* erkannt, Kollisionen mit $3fff werden gar nicht erkannt
* - X-expandierte Sprites mit X-Koordinaten >=$140 werden nicht angezeigt.
* Genaugenommen sollte ein Sprite nur dann unsichtbar sein, wenn die
* X-Koordinate zwischen $1f8 und $1ff liegt.
* - In den Bitmap-Darstellungen ab den Adressen $0000 und $8000 sollte
* eigentlich ab $1000/$9000 das Char-ROM sichtbar sein. Aus
* Geschwindigkeitsgründen wird in der Emulation das RAM darunter
* dargestellt. Dies sollte keine Rolle spielen, da diese Bitmap-Seiten
* aus dem genannten Grund von keinem Programm komplett verwendet werden.
* - Der IRQ wird bei jedem Schreibzugriff in das Flag-Register gelöscht.
* Das ist ein Hack für die RMW-Befehle des 6510, die zuerst den
* Originalwert schreiben.
* - Kein Lightpen-Interrupt
*
SPR_DATA_COLL SET 1 ;0 - Keine Sprite-Hintergrund-Prioritäten/-Kollisionen
MACHINE 68020
INCLUDE "exec/types.i"
INCLUDE "exec/macros.i"
INCLUDE "exec/nodes.i"
INCLUDE "graphics/rastport.i"
INCLUDE "libraries/cybergraphics.i"
XREF _SysBase ;Main.asm
XREF _GfxBase
XREF _CyberGfxBase
XREF TheRAM ;6510.asm
XREF TheChar
XREF TheColor
XREF IntIsVICIRQ
XREF CyclesLeft
XREF CountTODs ;6526.asm
XREF Periodic6526
XREF _OpenDisplay ;Display.c
XREF _RedrawDisplay
XREF _the_rast_port
XREF _temp_rp
XDEF Init6569
XDEF _GetVICDump
XDEF OpenGraphics
XDEF ChangedVA
XDEF ReadFrom6569
XDEF WriteTo6569
XDEF Periodic6569
XDEF DisplayID ;Prefs
XDEF ScreenType
XDEF NormalCycles
XDEF BadLineCycles
XDEF SpritesOn
XDEF Collisions
XDEF Overscan
XDEF SkipLatch
XDEF LimitSpeed
XDEF DirectVideo
SECTION "text",CODE
**
** Definitionen
**
; VIC-Register
M0Y = $01 ;Y-Position von Sprite 0
M1Y = $03 ;Y-Position von Sprite 1
M2Y = $05 ;Y-Position von Sprite 2
M3Y = $07 ;Y-Position von Sprite 3
M4Y = $09 ;Y-Position von Sprite 4
M5Y = $0b ;Y-Position von Sprite 5
M6Y = $0d ;Y-Position von Sprite 6
M7Y = $0f ;Y-Position von Sprite 7
MX8 = $10 ;Höchste Bits der Sprite X-Positionen
CTRL1 = $11 ;Steuerreg. 1
RASTER = $12 ;Rasterzähler
LPX = $13 ;Lightpen X
LPY = $14 ;Lightpen Y
SPREN = $15 ;Sprite eingeschaltet
CTRL2 = $16 ;Steuerreg. 2
MYE = $17 ;Sprite Y-Expansion
VBASE = $18 ;Basisadressen
IRQFLAG = $19 ;Interruptreg.
IRQMASK = $1a
MDP = $1b ;Sprite Priorität
MMC = $1c ;Sprite Multicolor
MXE = $1d ;Sprite X-Expansion
CLXSPR = $1e ;Kollisionsreg.
CLXBGR = $1f
EC = $20 ;Rahmenfarbe
B0C = $21 ;Hintergrundfarbe
; Zusätzliche Register
DISPLAYOFF = $2f ;Flag: $3fff wird dargestellt
IRQRASTER = $30 ;Rasterzeile, bei der ein IRQ ausgelöst wird (Wort)
XSCROLL = $32 ;X-Scroll-Wert (Wort)
YSCROLL = $34 ;Y-Scroll-Wert (Wort)
DXSTART = $36 ;Aktuelle Werte des Randbereichs
DXSTOP = $38
DYSTART = $3a
DYSTOP = $3c
RC = $3e ;Rasterzähler RC
MATRIXBASE = $40 ;Videomatrix-Basis (Amiga-Adresse)
CHARBASE = $44 ;Zeichengenerator-Basis (Amiga-Adresse)
BITMAPBASE = $48 ;Bitmap-Basis (Amiga-Adresse)
CURRENTA5 = $4c ;Augenblicklicher Zeiger im ChunkyBuf
;Speicher für a5 zwischen Aufrufen von Periodic6569
CURRENTRASTER = $50 ;Augenblickliche Rasterzeile
;Speicher für d7 zwischen Aufrufen von Periodic6569
LASTBKGD = $52 ;Letzte dargestellte Hintergrundfarbe
SPRITEON = $53 ;Sprite wird dargestellt, pro Sprite ein Bit
BORDERON = $54 ;Flag: Oberer/unterer Rahmen wird dargestellt
IS38COL = $55 ;Flag: 38 Spalten
BADLINEENABLE = $56 ;Flag: Bad Lines sind zugelassen
;In Zeile $30 wird Bit 4 in $D011 getestet und
; dieses Flag entsprechend gesetzt
SKIPFRAME = $57 ;Flag: Dieses Frame überspringen, nichts zeichnen
BADLINE = $58 ;Flag: Bad-Line-Zustand
MC0 = $5a ;Spritedatenzähler 0
MC1 = $5c
MC2 = $5e
MC3 = $60
MC4 = $62
MC5 = $64
MC6 = $66
MC7 = $68 ;Spritedatenzähler 7
VCBASE = $6a ;VC-Zwischenspeicher
VCCOUNT = $6c ;VC-Zähler
CIAVABASE = $6e ;16-Bit Basisadresse durch Cia-VA14/15
BORDERLONG = $70 ;Vorberechnete Farbwerte
BACK0LONG = $74
SPRX0 = $78 ;16-Bit Sprite-X-Koordinaten
SPRX1 = $7a
SPRX2 = $7c
SPRX3 = $7e
SPRX4 = $80
SPRX5 = $82
SPRX6 = $84
SPRX7 = $86
SPR0BASE = $88
SPR1BASE = $8a
SPR2BASE = $8c
SPR3BASE = $8e
SPR4BASE = $90
SPR5BASE = $92
SPR6BASE = $94
SPR7BASE = $96
VICRegLength = $98
; Anzahl Rasterzeilen
TotalRasters = $138
; Textfenster-Koordinaten (Stop-Werte sind immer eins mehr)
Row25YStart = $33
Row25YStop = $fb
Row24YStart = $37
Row24YStop = $f7
Col40XStart = $20
Col40XStop = $160
Col38XStart = $27
Col38XStop = $157
; Erste und letzte mögliche Zeile für Bad Lines
FirstDMALine = $30
LastDMALine = $f7
; Erste und letzte dargestellte Zeile
FirstDispLine = $10
LastDispLine = $11f ;eigentlich $12b
; Größe der Anzeige
DisplayX = $180 ;Muß ein Vielfaches von 32 sein (wg. c2p4)!
DisplayY = LastDispLine-FirstDispLine+1
; ScreenTypes
STYP_8BIT = 0 ;8-Bit-Screen, WritePixelLine8/
STYP_4BIT = 1 ;4-Bit-Screen, c2p4
STYP_1BIT = 2 :1-Bit-Screen, Amiga Mono
; cybergraphics.library
CYBRMATTR_ISLINEARMEM = $80000009
GetCyberMapAttr = -96
DoCDrawMethod = -156
*
* Makros
*
; Sprite darstellen
DoSprite MACRO ;Nummer
btst #\1,SPRITEON(a4) ;Wird das Sprite dargestellt?
beq \@1$
move.l MATRIXBASE(a4),a0
moveq #0,d0
move.b $03f8+\1(a0),d0 ;Datenzeiger
lsl.w #6,d0 ;*64
add.w MC\1(a4),d0 ;MC dazunehmen
bsr GetPhysical
move.l (a0),d0 ;d0: Spritedaten
move.w SPRX\1(a4),d1 ;d1: X-Koordinate
move.l a5,a1
add.w d1,a1
addq.l #8,a1 ;a1: Ziel im Bildschirmspeicher
lea SprCollBuf+8,a2
add.w d1,a2 ;a2: Ziel im Kollisionspuffer
IFNE SPR_DATA_COLL
lea GfxCollBuf+8,a3
add.w d1,a3 ;a3: Zeiger auf Grafik-Kollisionspuffer
ENDC
move.b $27+\1(a4),d2 ;d2: Spritefarbe
move.b #1<<\1,d7 ;d7: Sprite-Bit
move.l Sprite\1Proc,a0
jsr (a0)
\@1$
ENDM
**
** Emulation vorbereiten
**
*
* Register vorbereiten
*
Init6569 lea Registers,a0
move.w #7,RC(a0)
move.w #-1,CURRENTRASTER(a0)
move.l TheRAM,MATRIXBASE(a0)
move.l TheRAM,CHARBASE(a0)
move.l TheRAM,BITMAPBASE(a0)
clr.w CIAVABASE(a0)
move.w #63,MC0(a0)
move.w #63,MC1(a0)
move.w #63,MC2(a0)
move.w #63,MC3(a0)
move.w #63,MC4(a0)
move.w #63,MC5(a0)
move.w #63,MC6(a0)
move.w #63,MC7(a0)
bsr SetDispProc
bsr SetSpriteProcs
rts
*
* Screen und Fenster öffnen
* d0=0: Alles OK
* d0=1: Konnte Screen nicht öffnen
* d0=2: Kein Speicher
*
OpenGraphics pea DisplayY
pea DisplayX
moveq #0,d0
move.w Overscan,d0
move.l d0,-(sp)
move.l DisplayID,-(sp)
move.w ScreenType,d0
move.l d0,-(sp)
jsr _OpenDisplay
lea 20(sp),sp
tst.l d0
bne 1$
move.l _CURRENTA5,Registers+CURRENTA5
move.l _CyberGfxBase,d0
beq 2$
move.l a6,-(sp)
move.l d0,a6
move.l _the_rast_port,a0 ;Ist es eine CyberGfx-Bitmap?
move.l rp_BitMap(a0),a0
move.l #CYBRMATTR_ISCYBERGFX,d0
jsr GetCyberMapAttr(a6)
tst.l d0
beq 3$
move.l _the_rast_port,a0 ;Ja, Direkter Zugriff erlaubt?
move.l rp_BitMap(a0),a0
move.l #CYBRMATTR_ISLINEARMEM,d0
jsr GetCyberMapAttr(a6)
tst.l d0
beq 3$
sne IsCyber ;Ja, DoCDrawMethod kann benutzt werden
tst.w DirectVideo ;Zugriff ohne DoCDrawMethod gewünscht?
beq 3$
move.l _the_rast_port,a0 ;Ja, XMod und Basisadresse bestimmen
move.l rp_BitMap(a0),a0
move.l #CYBRMATTR_XMOD,d0
jsr GetCyberMapAttr(a6)
move.l d0,CyberXMod
move.l _the_rast_port,a0
move.l rp_BitMap(a0),a0
move.l #CYBRMATTR_DISPADR,d0
jsr GetCyberMapAttr(a6)
move.l d0,CyberBase
spl IsCyberDirect
3$
move.l (sp)+,a6
2$
moveq #0,d0
1$ rts
**
** VIC-Status in Datenstruktur schreiben
**
_GetVICDump lea Registers,a0
move.l 4(sp),a1
move.b SPRX0+1(a0),(a1)+
move.b M0Y(a0),(a1)+
move.b SPRX1+1(a0),(a1)+
move.b M1Y(a0),(a1)+
move.b SPRX2+1(a0),(a1)+
move.b M2Y(a0),(a1)+
move.b SPRX3+1(a0),(a1)+
move.b M3Y(a0),(a1)+
move.b SPRX4+1(a0),(a1)+
move.b M4Y(a0),(a1)+
move.b SPRX5+1(a0),(a1)+
move.b M5Y(a0),(a1)+
move.b SPRX6+1(a0),(a1)+
move.b M6Y(a0),(a1)+
move.b SPRX7+1(a0),(a1)+
move.b M7Y(a0),(a1)+
move.b MX8(a0),(a1)+
move.b CTRL1(a0),d0
and.b #$7f,d0
move.b CURRENTRASTER(a0),d1
lsl.b #7,d1
or.b d1,d0
move.b d0,(a1)+
move.b CURRENTRASTER+1(a0),(a1)+
lea LPX(a0),a0
moveq #27,d0 ;LPX..M7C
1$ move.b (a0)+,(a1)+
dbra d0,1$
lea Registers,a0
addq.l #1,a1
move.w IRQRASTER(a0),(a1)+
move.w VCCOUNT(a0),(a1)+
move.w VCBASE(a0),(a1)+
move.b RC+1(a0),(a1)+
move.b SPRITEON(a0),(a1)+
move.b MC0+1(a0),(a1)+
move.b MC1+1(a0),(a1)+
move.b MC2+1(a0),(a1)+
move.b MC3+1(a0),(a1)+
move.b MC4+1(a0),(a1)+
move.b MC5+1(a0),(a1)+
move.b MC6+1(a0),(a1)+
move.b MC7+1(a0),(a1)+
tst.b DISPLAYOFF(a0)
sne.b (a1)+
sne.b (a1)+
tst.b BADLINE(a0)
sne.b (a1)+
sne.b (a1)+
tst.b BADLINEENABLE(a0)
sne.b (a1)+
sne.b (a1)+
move.w CIAVABASE(a0),(a1)+
move.w MATRIXBASE+2(a0),(a1)+
move.w CHARBASE+2(a0),(a1)+
move.w BITMAPBASE+2(a0),(a1)+
move.l d2,-(sp)
move.w CIAVABASE(a0),d2
move.l MATRIXBASE(a0),a0
moveq #7,d1
lea $03f8(a0),a0
2$ moveq #0,d0
move.b (a0)+,d0
lsl.w #6,d0
or.w d2,d0
move.w d0,(a1)+
dbra d1,2$
move.l (sp)+,d2
rts
**
** CIA-VA14/15 hat sich geändert, Video-Bank wechseln
** d0.b: Neue VA ($00-$03)
**
ChangedVA lea Registers,a0 ;Wichtig für WrVBASE
clr.w d1 ;VABase speichern
move.b d0,d1
ror.w #2,d1
move.w d1,CIAVABASE(a0)
move.b VBASE(a0),d1 ;Zeiger neu berechnen
bra WrVBASE
**
** Aus einer VIC-16-Bit-Adresse die entsprechende Amiga-Adresse berechnen
** -> d0.w: 16-Bit-Adresse
** <- a0.l: 32-Bit-Adresse
**
GetPhysical or.w CIAVABASE(a4),d0 ;VA14/15 dazunehmen
move.w d0,d1
and.w #$7000,d1
cmp.w #$1000,d1
beq 1$
move.l TheRAM,a0
moveq #0,d1
move.w d0,d1
add.l d1,a0
rts
1$ and.w #$0fff,d0 ;$1000-$1fff, $9000-$9fff: Char-ROM
move.l TheChar,a0
add.w d0,a0
rts
**
** Aus einem VIC-Register lesen
** d0.l: Registernummer ($00-$3f)
** Rückgabe: d0.b: Byte
**
** Darf das obere Wort von d0 und d1 nicht verändern!
**
ReadFrom6569 lea Registers,a0
move.l ReadTab(pc,d0.l*4),a1
jmp (a1)
CNOP 0,4
ReadTab dc.l RdSprX
dc.l RdNormal
dc.l RdSprX
dc.l RdNormal
dc.l RdSprX
dc.l RdNormal
dc.l RdSprX
dc.l RdNormal
dc.l RdSprX
dc.l RdNormal
dc.l RdSprX
dc.l RdNormal
dc.l RdSprX
dc.l RdNormal
dc.l RdSprX
dc.l RdNormal
dc.l RdNormal
dc.l RdCTRL1
dc.l RdRASTER
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdCTRL2
dc.l RdNormal
dc.l RdVBASE
dc.l RdIRQFLAG
dc.l RdIRQMASK
dc.l RdNormal
dc.l RdNormal
dc.l RdNormal
dc.l RdCLXSPR
dc.l RdCLXBGR
dc.l RdColor
dc.l RdColor
dc.l RdColor
dc.l RdColor
dc.l RdColor
dc.l RdColor
dc.l RdColor
dc.l RdColor
dc.l RdColor
dc.l RdColor
dc.l RdColor
dc.l RdColor
dc.l RdColor
dc.l RdColor
dc.l RdColor
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
dc.l RdUndef
RdNormal move.b (a0,d0.l),d0
rts
RdSprX move.b SPRX0+1(a0,d0.l),d0 ;LSB lesen
rts
RdCTRL1 move.b CTRL1(a0),d0
and.b #$7f,d0
move.b CURRENTRASTER(a0),d1 ;MSB des Rasterzählers lesen
lsl.b #7,d1
or.b d1,d0 ;und dazunehmen
rts
RdRASTER move.b CURRENTRASTER+1(a0),d0 ;Rasterzähler lesen
rts
RdCTRL2 move.b CTRL2(a0),d0
or.b #$c0,d0 ;Unbenutzte Bits auf 1
rts
RdVBASE move.b VBASE(a0),d0
or.b #$01,d0 ;Unbenutzte Bits auf 1
rts
RdIRQFLAG move.b IRQFLAG(a0),d0
or.b #$70,d0 ;Unbenutzte Bits auf 1
rts
RdIRQMASK move.b IRQMASK(a0),d0
or.b #$f0,d0 ;Unbenutzte Bits auf 1
rts
RdCLXSPR lea CLXSPR(a0),a0
move.b (a0),d0 ;Lesen und löschen
clr.b (a0)
rts
RdCLXBGR lea CLXBGR(a0),a0
move.b (a0),d0 ;Lesen und löschen
clr.b (a0)
rts
RdColor move.b (a0,d0.l),d0 ;Bei den Farbregistern
or.b #$f0,d0 ;das obere Nibble setzen
rts
RdUndef st.b d0 ;Nicht existierendes Register
rts
**
** In ein VIC-Register schreiben
** d0.l: Registernummer ($00-$3f)
** d1.b: Byte
**
** Darf das obere Wort von d0 und d1 nicht verändern!
**
WriteTo6569 lea Registers,a0
move.l WriteTab(pc,d0.l*4),a1
jmp (a1)
CNOP 0,4
WriteTab dc.l WrSprX
dc.l WrNormal
dc.l WrSprX
dc.l WrNormal
dc.l WrSprX
dc.l WrNormal
dc.l WrSprX
dc.l WrNormal
dc.l WrSprX
dc.l WrNormal
dc.l WrSprX
dc.l WrNormal
dc.l WrSprX
dc.l WrNormal
dc.l WrSprX
dc.l WrNormal
dc.l WrSprXMSB
dc.l WrCTRL1
dc.l WrRASTER
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrCTRL2
dc.l WrNormal
dc.l WrVBASE
dc.l WrIRQFLAG
dc.l WrIRQMASK
dc.l WrMDP
dc.l WrMMC
dc.l WrMXE
dc.l WrUndef
dc.l WrUndef
dc.l WrBorder
dc.l WrBack0
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrNormal
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
dc.l WrUndef
WrNormal move.b d1,(a0,d0.l)
WrUndef rts
WrSprX move.b d1,SPRX0+1(a0,d0.l)
rts
WrSprXMSB move.b d1,MX8(a0)
lea SPRX7(a0),a0 ;MSBs in 16-Bit-Werte umrechnen
moveq #7,d0
1$ add.b d1,d1
bcs 2$
clr.b (a0)
bra 3$
2$ move.b #1,(a0)
3$ subq.w #2,a0
dbra d0,1$
rts
WrCTRL1 move.b d1,CTRL1(a0)
move.b d1,d0 ;Y-Scroll
and.w #7,d0
move.w d0,YSCROLL(a0)
move.b d1,d0 ;MSB der IRQ-Rasterzeile
lsr.b #7,d0
move.b d0,IRQRASTER(a0)
btst #3,d1 ;24/25 Zeilen
beq 1$
move.w #Row25YStart,DYSTART(a0)
move.w #Row25YStop,DYSTOP(a0)
bra SetDispProc
1$ move.w #Row24YStart,DYSTART(a0)
move.w #Row24YStop,DYSTOP(a0)
bra SetDispProc
SetDispProc moveq #0,d0 ;ECM, BMM und MCM holen
move.b CTRL1(a0),d0
and.b #$60,d0
move.b CTRL2(a0),d1
and.b #$10,d1
or.b d1,d0
lsr.b #2,d0 ;Als Index in DispProcTab benutzen
cmp.w #STYP_1BIT,ScreenType
beq 1$
move.l (DispProcTab,pc,d0.l),DisplayProc
rts
1$ move.l (MonoDispProcTab,pc,d0.l),DisplayProc
rts
WrRASTER move.b d1,IRQRASTER+1(a0)
rts
WrCTRL2 move.b d1,CTRL2(a0)
move.b d1,d0 ;X-Scroll
and.w #7,d0
move.w d0,XSCROLL(a0)
btst #3,d1 ;38/40 Zeilen
seq.b IS38COL(a0)
beq 1$
move.w #Col40XStart,DXSTART(a0)
move.w #Col40XStop,DXSTOP(a0)
bra SetDispProc
1$ move.w #Col38XStart,DXSTART(a0)
move.w #Col38XStop,DXSTOP(a0)
bra SetDispProc
WrVBASE move.l a0,a1 ;a1: Zeiger auf Register
move.b d1,VBASE(a1)
move.l a4,-(sp)
move.l a1,a4 ;Für GetPhysical
move.w d1,-(sp)
move.b d1,d0 ;Videomatrixbasis berechnen
and.w #$f0,d0
lsl.w #6,d0
bsr GetPhysical
move.l a0,MATRIXBASE(a1)
move.w (sp),d1 ;Nur lesen, nicht entfernen
move.b d1,d0 ;Zeichengeneratorbasis berechnen
and.w #$0e,d0
ror.w #6,d0
bsr GetPhysical
move.l a0,CHARBASE(a1)
move.w (sp)+,d1
move.b d1,d0
and.w #$08,d0
ror.w #6,d0
bsr GetPhysical
move.l a0,BITMAPBASE(a1)
move.l (sp)+,a4
rts
WrIRQFLAG not.b d1 ;Gesetztes Bit: Flag löschen
and.b #$0f,d1
move.b IRQFLAG(a0),d0
and.b d1,d0
clr.b IntIsVICIRQ ;IRQ zurücknehmen (Hack!)
move.b d0,d1 ;Erlaubter IRQ noch gesetzt?
and.b IRQMASK(a0),d1
beq 1$
or.b #$80,d0 ;Ja, Master-Bit setzen
1$ move.b d0,IRQFLAG(a0)
rts
WrIRQMASK and.b #$0f,d1
move.b d1,IRQMASK(a0)
and.b IRQFLAG(a0),d1 ;Gesetzter IRQ jetzt erlaubt?
beq 1$
or.b #$80,IRQFLAG(a0) ;Ja, Master-Bit setzen
st.b IntIsVICIRQ ; und Interrupt auslösen
rts
1$ clr.b IntIsVICIRQ ;Nein, Interrupt zurücknehmen
and.b #$7f,IRQFLAG(a0) ; und Master-Bit löschen
rts
WrMDP move.b d1,MDP(a0)
bra SetSpriteProcs
WrMMC move.b d1,MMC(a0)
bra SetSpriteProcs
WrMXE move.b d1,MXE(a0) ;Fällt durch!
SetSpriteProcs moveq #7,d1
lea Sprite7Proc,a1
1$ moveq #0,d0
btst d1,MXE(a0)
beq 2$
or.b #1,d0
2$ btst d1,MMC(a0)
beq 3$
or.b #2,d0
3$ btst d1,MDP(a0)
beq 4$
or.b #4,d0
4$ move.l (SpriteProcTab,pc,d0.l*4),(a1)
subq.w #4,a1
dbra d1,1$
rts
WrBorder move.b d1,EC(a0)
move.b d1,d0 ;In ein Langwort konvertieren
lsl.w #8,d0
move.b d1,d0
move.w d0,d1
swap d0
move.w d1,d0
move.l d0,BORDERLONG(a0)
moveq #0,d0
rts
WrBack0 move.b d1,B0C(a0)
move.b d1,d0 ;In ein Langwort konvertieren
lsl.w #8,d0
move.b d1,d0
move.w d0,d1
swap d0
move.w d1,d0
move.l d0,BACK0LONG(a0)
moveq #0,d0
rts
**
** Eine Rasterzeile des VIC ausführen
**
** d7: Rasterzeilenzähler
** a4: Zeiger auf VIC-Register
** a5: Zeiger auf das Ziel im Bildschirmspeicher
**
; VBlank: Zähler zurücksetzen
VICVBlank move.w #-1,CURRENTRASTER(a4)
clr.w VCBASE(a4)
bsr CountTODs ;TODs zählen
subq.w #1,SkipCounter
sne SKIPFRAME(a4)
bne Periodic6569
move.w SkipLatch,SkipCounter
; Grafik darstellen
jsr _RedrawDisplay
move.l _CURRENTA5,CURRENTA5(a4)
; CyberDirect: Basisadresse des Bildschirmspeichers holen
tst.b IsCyberDirect
beq 1$
move.l _CyberGfxBase,a6
move.l _the_rast_port,a0
move.l rp_BitMap(a0),a0
move.l #CYBRMATTR_DISPADR,d0
jsr GetCyberMapAttr(a6)
move.l d0,CyberBase
1$
;fällt durch!
*
* Aktuelle Rasterzeile holen
*
Periodic6569 lea Registers,a4
move.w CURRENTRASTER(a4),d7
*
* Rasterzähler erhöhen (muß hier geschehen, damit bei einem Raster-IRQ
* der Wert des Rasterzählers mit der IRQ-Zeile übereinstimmt)
*
addq.w #1,d7
move.w d7,CURRENTRASTER(a4)
cmp.w #TotalRasters,d7 ;Bildende erreicht?
beq VICVBlank
*
* Raster-IRQ auslösen, wenn Vergeichswert erreicht
*
cmp.w IRQRASTER(a4),d7 ;IRQ-Zeile erreicht?
bne NoRasterIRQ
bsr DoRasterIRQ
NoRasterIRQ
*
* In Zeile $30 entscheidet das DEN-Bit, ob Bad Lines auftreten dürfen
*
cmp.w #$30,d7
bne 1$
btst #4,CTRL1(a4)
sne BADLINEENABLE(a4)
1$
*
* Neue Anzahl CPU-Zyklen setzen
*
move.w NormalCycles,CyclesLeft
tst.b SKIPFRAME(a4)
bne VICSkip
*
* Innerhalb des sichtbaren Bereichs?
*
cmp.w #FirstDispLine,d7
blo VICNop
cmp.w #LastDispLine,d7
bhi VICNop
*
* Zeiger in Bildschirmspeicher nach a5 holen
*
move.l CURRENTA5(a4),a5
*
* VC-Zähler setzen
*
move.w VCBASE(a4),VCCOUNT(a4)
clr.b BADLINE(a4)
*
* Bei Amiga-Mono in Mono-VIC-Routine verzweigen
*
cmp.w #STYP_1BIT,ScreenType
beq AmigaMono6569
*
* "Bad Lines"-Videomatrixzugriff:
* 40 Bytes aus Videomatrix und Farb-RAM lesen und zwischenspeichern
*
tst.b BADLINEENABLE(a4) ;War das DEN-Bit in Rasterzeile $30 gesetzt?
beq NoBadLine
cmp.w #FirstDMALine,d7 ;Innerhalb des DMA-Bereiches?
blo NoBadLine
cmp.w #LastDMALine,d7
bhi NoBadLine
move.b d7,d0 ;Ja, stimmen die unteren Bits
and.b #7,d0 ;der Rasterzeile mit dem Y-Scroll
cmp.b YSCROLL+1(a4),d0 ;überein?
bne NoBadLine
IsBadLine st.b BADLINE(a4) ;Ja, Bad Line
move.w VCCOUNT(a4),d2 ;d2: VC Videomatrix-Zähler
move.l MATRIXBASE(a4),a0 ;Videomatrixbasis holen
add.w d2,a0 ;Videomatrixzähler dazunehmen
move.l TheColor,a2 ;Zeiger auf Farb-RAM holen
add.w d2,a2 ;Videomatrixzähler dazunehmen
lea MatrixLine,a1 ;Videomatrix- und Farb-RAM-Zeile lesen
lea ColorLine,a3
movem.l (a0)+,d0-d6 ;Je 40 Bytes kopieren
movem.l d0-d6,(a1)
movem.l (a2)+,d0-d6
movem.l d0-d6,(a3)
movem.l (a0)+,d0-d2
movem.l d0-d2,28(a1)
movem.l (a2)+,d0-d2
movem.l d0-d2,28(a3)
clr.w RC(a4) ;RC zurücksetzen
clr.b DISPLAYOFF(a4) ;Darstellung anschalten
move.w BadLineCycles,CyclesLeft ;Andere Anzahl Zyklen
NoBadLine
*
* Oberen und unteren Rahmen handhaben
*
cmp.w DYSTOP(a4),d7 ;Unteres Ende des Fensters erreicht?
bne 1$ ; -> Rahmen einschalten
st.b BORDERON(a4)
bra TBBorderDraw
1$ btst #4,CTRL1(a4) ;Rahmen nur abschalten, wenn DEN-Bit gesetzt
beq TBBorderDone
cmp.w DYSTART(a4),d7 ;Oberes Ende des Fensters erreicht?
bne TBBorderDone ; -> Rahmen abschalten
clr.b BORDERON(a4)
bra TBNoBorder
TBBorderDone tst.b BORDERON(a4) ;Rahmen an?
beq TBNoBorder
TBBorderDraw move.l a5,a0 ;Ja, Rahmen malen.
move.l BORDERLONG(a4),d0 ;d0.l: Rahmenfarbe
moveq #DisplayX/4-1,d1
1$ move.l d0,(a0)+
dbra d1,1$
bra VICIncA5 ;Sonst nix
TBNoBorder
*
* Inhalt des Fensters: Darstellung eingeschaltet?
*
lea Col40XStart(a5),a1
add.w XSCROLL(a4),a1 ;a1: Ziel in Bildschirmspeicher
lea MatrixLine,a2 ;a2: Zeichencodes
lea ColorLine,a3 ;a3: Farbcodes
IFNE SPR_DATA_COLL
lea GfxCollBuf+Col40XStart,a6
add.w XSCROLL(a4),a6 ;a6: Grafik-Kollisionspuffer
ENDC
tst.b DISPLAYOFF(a4) ;$3FFF darstellen?
bne Show3FFF
move.l DisplayProc,a0 ;Nein, Routine für entsp. Modus anspringen
jmp (a0)
*
* Standard-Text: Zeichendaten holen und darstellen
*
TextStd add.w #40,VCCOUNT(a4) ;VC erhöhen (wird nicht verwendet)
move.l CHARBASE(a4),a0 ;a0: Zeichengeneratorbasis
add.w RC(a4),a0 ;RC dazunehmen
move.l BACK0LONG(a4),d3 ;d3.l: Hintergrundfarbe
move.l d3,Col40XStart(a5) ;Hintergrund, wenn X-Scroll>0
move.l d3,Col40XStart+4(a5)
; Schleife für 40 Zeichen
moveq #39,d1 ;d1: Zeichenzähler
moveq #0,d0
CharLoop move.b (a2)+,d0 ;Zeichencode lesen
move.b (a0,d0.l*8),d0 ;Zeichendaten lesen
beq OnlyBack
move.b (a3)+,d2 ;d2: Zeichenfarbe
; 8 Pixel konvertieren
add.b d0,d0
bcc 11$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 12$
11$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
12$ add.b d0,d0
bcc 21$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 22$
21$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
22$ add.b d0,d0
bcc 31$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 32$
31$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
32$ add.b d0,d0
bcc 41$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 42$
41$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
42$ add.b d0,d0
bcc 51$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 52$
51$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
52$ add.b d0,d0
bcc 61$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 62$
61$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
62$ add.b d0,d0
bcc 71$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 72$
71$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
72$ add.b d0,d0
bcc 81$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 82$
81$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
82$ dbra d1,CharLoop
bra DoSprites
; Nur Hintergrund
CNOP 0,4
OnlyBack move.l d3,(a1)+
move.l d3,(a1)+
IFNE SPR_DATA_COLL
clr.l (a6)+
clr.l (a6)+
ENDC
addq.w #1,a3 ;Farb-RAM-Byte überspringen
dbra d1,CharLoop
bra DoSprites
*
* Multicolor-Text: Zeichendaten holen und darstellen
*
TextMulti add.w #40,VCCOUNT(a4) ;VC erhöhen (wird nicht verwendet)
move.l CHARBASE(a4),a0 ;a0: Zeichengeneratorbasis
add.w RC(a4),a0 ;RC dazunehmen
move.l BACK0LONG(a4),d3 ;d3.l: Farbe 0
move.w $22(a4),d4 ;d4.w: Farbe 1
move.b $22(a4),d4
move.w $23(a4),d5 ;d5.w: Farbe 2
move.b $23(a4),d5
move.l d3,Col40XStart(a5) ;Hintergrund, wenn X-Scroll>0
move.l d3,Col40XStart+4(a5)
; Schleife für 40 Zeichen
moveq #39,d1 ;d1: Zeichenzähler
moveq #0,d0
CharMLoop move.b (a2)+,d0 ;Zeichencode lesen
move.b (a0,d0.l*8),d0 ;Zeichendaten lesen
beq MOnlyBack
move.b (a3)+,d2 ;d2: Farbnibble
bclr #3,d2 ;Standard oder Multi?
beq StdInMulti
; Multicolor: 4 Pixel konvertieren
add.b d0,d0
bcc 11$
add.b d0,d0
bcc 12$
move.b d2,(a1)+ ;11
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 14$
12$ move.w d5,(a1)+ ;10
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 14$
11$
IFNE SPR_DATA_COLL
clr.w (a6)+
ENDC
add.b d0,d0
bcc 13$
move.w d4,(a1)+ ;01
bra 14$
13$ move.w d3,(a1)+ ;00
14$
add.b d0,d0
bcc 21$
add.b d0,d0
bcc 22$
move.b d2,(a1)+ ;11
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 24$
22$ move.w d5,(a1)+ ;10
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 24$
21$
IFNE SPR_DATA_COLL
clr.w (a6)+
ENDC
add.b d0,d0
bcc 23$
move.w d4,(a1)+ ;01
bra 24$
23$ move.w d3,(a1)+ ;00
24$
add.b d0,d0
bcc 31$
add.b d0,d0
bcc 32$
move.b d2,(a1)+ ;11
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 34$
32$ move.w d5,(a1)+ ;10
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 34$
31$
IFNE SPR_DATA_COLL
clr.w (a6)+
ENDC
add.b d0,d0
bcc 33$
move.w d4,(a1)+ ;01
bra 34$
33$ move.w d3,(a1)+ ;00
34$
add.b d0,d0
bcc 41$
add.b d0,d0
bcc 42$
move.b d2,(a1)+ ;11
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 44$
42$ move.w d5,(a1)+ ;10
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 44$
41$
IFNE SPR_DATA_COLL
clr.w (a6)+
ENDC
add.b d0,d0
bcc 43$
move.w d4,(a1)+ ;01
bra 44$
43$ move.w d3,(a1)+ ;00
44$
dbra d1,CharMLoop
bra DoSprites
; Standard: 8 Pixel konvertieren
CNOP 0,4
StdInMulti add.b d0,d0
bcc 11$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 12$
11$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
12$ add.b d0,d0
bcc 21$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 22$
21$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
22$ add.b d0,d0
bcc 31$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 32$
31$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
32$ add.b d0,d0
bcc 41$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 42$
41$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
42$ add.b d0,d0
bcc 51$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 52$
51$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
52$ add.b d0,d0
bcc 61$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 62$
61$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
62$ add.b d0,d0
bcc 71$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 72$
71$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
72$ add.b d0,d0
bcc 81$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 82$
81$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
82$ dbra d1,CharMLoop
bra DoSprites
; Nur Hintergrund
CNOP 0,4
MOnlyBack move.l d3,(a1)+
move.l d3,(a1)+
IFNE SPR_DATA_COLL
clr.l (a6)+
clr.l (a6)+
ENDC
addq.w #1,a3 ;Farb-RAM-Byte überspringen
dbra d1,CharMLoop
bra DoSprites
*
* Extended Color Mode: Grafikdaten holen und darstellen
*
TextECM add.w #40,VCCOUNT(a4) ;VC erhöhen (wird nicht verwendet)
move.l CHARBASE(a4),a0 ;a0: Zeichengeneratorbasis
add.w RC(a4),a0 ;RC dazunehmen
move.b $21(a4),d3 ;d3: Hintergrund 0
move.b $22(a4),d4 ;d4: Hintergrund 1
move.b $23(a4),d5 ;d5: Hintergrund 2
move.w LASTBKGD(a4),d0 ;Letzter Hintergrund, wenn X-Scroll>0
move.b LASTBKGD(a4),d0
move.w d0,Col40XStart(a5)
move.w d0,Col40XStart+2(a5)
move.w d0,Col40XStart+4(a5)
move.w d0,Col40XStart+6(a5)
; Schleife für 40 Zeichen
; d7: Aktuelle Hintergrundfarbe
moveq #39,d1 ;d1: Zeichenzähler
moveq #0,d0
CharELoop move.b (a2)+,d0 ;Zeichencode lesen
move.b (a3)+,d2 ;d2: Farbnibble
bclr #7,d0
bne 1$
bclr #6,d0
bne 2$
move.b d3,d7 ;00: Hintergrund 0
bra 4$
2$ move.b d4,d7 ;01: Hintergrund 1
bra 4$
1$ bclr #6,d0
bne 3$
move.b d5,d7 ;10: Hintergrund 2
bra 4$
3$ move.b $24(a4),d7 ;11: Hintergrund 3
4$ move.b (a0,d0.l*8),d0 ;Zeichendaten lesen
beq EOnlyBack
; 8 Pixel konvertieren
add.b d0,d0
bcc 11$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 12$
11$ move.b d7,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
12$ add.b d0,d0
bcc 21$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 22$
21$ move.b d7,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
22$ add.b d0,d0
bcc 31$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 32$
31$ move.b d7,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
32$ add.b d0,d0
bcc 41$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 42$
41$ move.b d7,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
42$ add.b d0,d0
bcc 51$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 52$
51$ move.b d7,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
52$ add.b d0,d0
bcc 61$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 62$
61$ move.b d7,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
62$ add.b d0,d0
bcc 71$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 72$
71$ move.b d7,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
72$ add.b d0,d0
bcc 81$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 82$
81$ move.b d7,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
82$ dbra d1,CharELoop
move.b d7,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
move.w CURRENTRASTER(a4),d7 ;d7 wurde zerstört
bra DoSprites
; Nur Hintergrund
CNOP 0,4
EOnlyBack move.b d7,(a1)+
move.b d7,(a1)+
move.b d7,(a1)+
move.b d7,(a1)+
move.b d7,(a1)+
move.b d7,(a1)+
move.b d7,(a1)+
move.b d7,(a1)+
IFNE SPR_DATA_COLL
clr.l (a6)+
clr.l (a6)+
ENDC
dbra d1,CharELoop
move.b d7,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
move.w CURRENTRASTER(a4),d7 ;d7 wurde zerstört
bra DoSprites
*
* Standard-BitMap: Grafikdaten holen und darstellen
*
BitMapStd move.l BITMAPBASE(a4),a0 ;a0: Bitmap-Basis
move.w VCCOUNT(a4),d0 ;VC holen
lsl.w #3,d0 ;*8
add.w RC(a4),d0 ;RC dazunehmen
add.w d0,a0 ;und zur Bitmap-Basis dazunehmen
add.w #40,VCCOUNT(a4) ;VC erhöhen
move.w LASTBKGD(a4),d0 ;Letzter Hintergrund, wenn X-Scroll>0
move.b LASTBKGD(a4),d0
move.w d0,Col40XStart(a5)
move.w d0,Col40XStart+2(a5)
move.w d0,Col40XStart+4(a5)
move.w d0,Col40XStart+6(a5)
; Schleife für 40 Bytes
moveq #39,d1 ;d1: Zeichenzähler
BitMapLoop move.b (a2)+,d2 ;Farbe holen
move.b d2,d3 ;d3: Hintergrundfarbe
move.b (a0),d0 ;Byte holen
beq BOnlyBack
lsr.b #4,d2 ;d2: Vordergrundfarbe
; 8 Pixel konvertieren
add.b d0,d0
bcc 11$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 12$
11$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
12$ add.b d0,d0
bcc 21$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 22$
21$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
22$ add.b d0,d0
bcc 31$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 32$
31$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
32$ add.b d0,d0
bcc 41$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 42$
41$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
42$ add.b d0,d0
bcc 51$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 52$
51$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
52$ add.b d0,d0
bcc 61$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 62$
61$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
62$ add.b d0,d0
bcc 71$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 72$
71$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
72$ add.b d0,d0
bcc 81$
move.b d2,(a1)+
IFNE SPR_DATA_COLL
st.b (a6)+
ENDC
bra 82$
81$ move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.b (a6)+
ENDC
82$ addq.l #8,a0 ;Quellzeiger erhöhen
dbra d1,BitMapLoop
move.b d3,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
bra DoSprites
; Nur Hintergrund
CNOP 0,4
BOnlyBack move.b d3,(a1)+
move.b d3,(a1)+
move.b d3,(a1)+
move.b d3,(a1)+
move.b d3,(a1)+
move.b d3,(a1)+
move.b d3,(a1)+
move.b d3,(a1)+
IFNE SPR_DATA_COLL
clr.l (a6)+
clr.l (a6)+
ENDC
addq.l #8,a0 ;Quellzeiger erhöhen
dbra d1,BitMapLoop
move.b d3,LASTBKGD(a4) ;Letzte Hintergrundfarbe merken
bra DoSprites
*
* Multicolor-Bitmap: Grafikdaten holen und darstellen
*
BitMapMulti move.l BITMAPBASE(a4),a0 ;a0: Bitmap-Basis
move.w VCCOUNT(a4),d0 ;VC holen
lsl.w #3,d0 ;*8
add.w RC(a4),d0 ;RC dazunehmen
add.w d0,a0 ;und zur Bitmap-Basis dazunehmen
add.w #40,VCCOUNT(a4) ;VC erhöhen
move.l BACK0LONG(a4),d5 ;d5.w: Farbe 0
move.l d5,Col40XStart(a5) ;Hintergrund, wenn X-Scroll>0
move.l d5,Col40XStart+4(a5)
; Schleife für 40 Bytes
moveq #39,d1
BitMapMLoop move.b (a2)+,d2 ;Farbe 1/2 holen
move.b (a0),d0 ;Byte holen
beq BMOnlyBack
move.b d2,d3 ;d3.b: Farbe 2
lsl.w #8,d3
move.b d2,d3
lsr.b #4,d2 ;d2.b: Farbe 1
move.b (a3),d4 ;d4.b: Farbe 3
lsl.w #8,d4
move.b (a3)+,d4
; 4 Pixel konvertieren
add.b d0,d0
bcc 11$
add.b d0,d0
bcc 12$
move.w d4,(a1)+ ;11
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 14$
12$ move.w d3,(a1)+ ;10
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 14$
11$
IFNE SPR_DATA_COLL
clr.w (a6)+
ENDC
add.b d0,d0
bcc 13$
move.b d2,(a1)+ ;01
move.b d2,(a1)+
bra 14$
13$ move.w d5,(a1)+ ;00
14$
add.b d0,d0
bcc 21$
add.b d0,d0
bcc 22$
move.w d4,(a1)+ ;11
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 24$
22$ move.w d3,(a1)+ ;10
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 24$
21$
IFNE SPR_DATA_COLL
clr.w (a6)+
ENDC
add.b d0,d0
bcc 23$
move.b d2,(a1)+ ;01
move.b d2,(a1)+
bra 24$
23$ move.w d5,(a1)+ ;00
24$
add.b d0,d0
bcc 31$
add.b d0,d0
bcc 32$
move.w d4,(a1)+ ;11
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 34$
32$ move.w d3,(a1)+ ;10
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 34$
31$
IFNE SPR_DATA_COLL
clr.w (a6)+
ENDC
add.b d0,d0
bcc 33$
move.b d2,(a1)+ ;01
move.b d2,(a1)+
bra 34$
33$ move.w d5,(a1)+ ;00
34$
add.b d0,d0
bcc 41$
add.b d0,d0
bcc 42$
move.w d4,(a1)+ ;11
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 44$
42$ move.w d3,(a1)+ ;10
IFNE SPR_DATA_COLL
st.b (a6)+
st.b (a6)+
ENDC
bra 44$
41$
IFNE SPR_DATA_COLL
clr.w (a6)+
ENDC
add.b d0,d0
bcc 43$
move.b d2,(a1)+ ;01
move.b d2,(a1)+
bra 44$
43$ move.w d5,(a1)+ ;00
44$
addq.l #8,a0 ;Quellzeiger erhöhen
dbra d1,BitMapMLoop
bra DoSprites
; Nur Hintergrund
CNOP 0,4
BMOnlyBack move.l d5,(a1)+
move.l d5,(a1)+
IFNE SPR_DATA_COLL
clr.l (a6)+
clr.l (a6)+
ENDC
addq.w #1,a3 ;Farb-RAM-Byte überspringen
addq.l #8,a0 ;Quellzeiger erhöhen
dbra d1,BitMapMLoop
bra DoSprites
*
* Ungültiger Darstellungsmodus: Schwarzen Bildschirm anzeigen
*
BlackScreen add.w #40,VCCOUNT(a4) ;VC erhöhen
moveq #39,d0 ;40 Zeichen schwarz
1$ clr.l (a1)+
clr.l (a1)+
IFNE SPR_DATA_COLL
clr.l (a6)+
clr.l (a6)+
ENDC
dbra d0,1$
bra DoSprites
*
* $3FFF darstellen
*
Show3FFF move.l BACK0LONG(a4),d3 ;d3.w: Hintergrundfarbe
move.l d3,Col40XStart(a5) ;Hintergrund, wenn X-Scroll>0
move.l d3,Col40XStart+4(a5)
btst #6,CTRL1(a4)
bne 11$
move.w #$3fff,d0 ;Byte bei $3FFF lesen
bra 12$
11$ move.w #$39ff,d0 ;ECM: Byte bei $39FF lesen
12$ bsr GetPhysical
move.b (a0),d0 ;Byte lesen
; 4 Pixel nach d1 konvertieren, 0: Hintergrund, 1: schwarz
moveq #0,d1
add.b d0,d0
bcs 1$
move.b d3,d1
1$ lsl.w #8,d1
add.b d0,d0
bcs 2$
move.b d3,d1
2$ lsl.l #8,d1
add.b d0,d0
bcs 3$
move.b d3,d1
3$ lsl.l #8,d1
add.b d0,d0
bcs 4$
move.b d3,d1
4$
; 4 Pixel nach d2 konvertieren
moveq #0,d2
add.b d0,d0
bcs 5$
move.b d3,d2
5$ lsl.w #8,d2
add.b d0,d0
bcs 6$
move.b d3,d2
6$ lsl.l #8,d2
add.b d0,d0
bcs 7$
move.b d3,d2
7$ lsl.l #8,d2
add.b d0,d0
bcs 8$
move.b d3,d2
8$
; Zeile schreiben
moveq #39,d0 ;d0: Bytezähler
Loop3FFF move.l d1,(a1)+
move.l d2,(a1)+
IFNE SPR_DATA_COLL
clr.l (a6)+ ;Falsch!!
clr.l (a6)+
ENDC
dbra d0,Loop3FFF
*
* Sprites malen?
*
DoSprites tst.b SPRITEON(a4) ;Ist überhaupt ein Sprite z.Z. sichtbar?
beq DrawLRBorder ;Nein, dann Rahmen
tst.w SpritesOn ;Sprite-Darstellung angeschaltet?
beq DrawLRBorder
*
* Mindestens ein Sprite ist sichtbar, Sprites malen
*
; Kollisions-Puffer löschen
lea SprCollBuf,a0
moveq #DisplayX/4-1,d0
1$ clr.l (a0)+
dbra d0,1$
; Sprites malen
moveq #0,d4 ;Sprite-Grafik Kollisionsflag
moveq #0,d5 ;Sprite-Sprite Kollisionsflag
DoSprite 0
DoSprite 1
DoSprite 2
DoSprite 3
DoSprite 4
DoSprite 5
DoSprite 6
DoSprite 7
move.w CURRENTRASTER(a4),d7 ;d7 wurde zerstört
; Kollisions-Flags auswerten
tst.w Collisions
beq DrawLRBorder
move.b CLXSPR(a4),d0
or.b d5,CLXSPR(a4) ;Bits im Kollisionsregister setzen
tst.b d0 ;Haben bereits Kollisionen stattgefunden?
bne 2$
or.b #$04,IRQFLAG(a4) ;Nein, IMMC-Bit setzen
btst #2,IRQMASK(a4) ;IRQ erlaubt?
beq 2$
or.b #$80,IRQFLAG(a4) ;Ja, IRQ-Bit setzen
st.b IntIsVICIRQ ;Und Interrupt auslösen
2$ move.b CLXBGR(a4),d0
or.b d4,CLXBGR(a4)
tst.b d0
bne DrawLRBorder
or.b #$02,IRQFLAG(a4)
btst #1,IRQMASK(a4)
beq DrawLRBorder
or.b #$80,IRQFLAG(a4)
st.b IntIsVICIRQ
*
* Linken und rechten Rahmen zeichnen
*
; 40-Spalten-Rahmen
DrawLRBorder move.l a5,a0
move.l BORDERLONG(a4),d0 ;d0.l: Rahmenfarbe
move.l d0,(a0)+ ;Links: $00..$1f
move.l d0,(a0)+
move.l d0,(a0)+
move.l d0,(a0)+
move.l d0,(a0)+
move.l d0,(a0)+
move.l d0,(a0)+
move.l d0,(a0)+
lea Col40XStop-Col40XStart(a0),a0
move.l d0,(a0)+ ;Rechts: $160..$17f
move.l d0,(a0)+
move.l d0,(a0)+
move.l d0,(a0)+
move.l d0,(a0)+
move.l d0,(a0)+
move.l d0,(a0)+
move.l d0,(a0)
; 38-Spalten-Rahmen
tst.b IS38COL(a4)
beq 1$
lea Col40XStart(a5),a0
move.l d0,(a0)+ ;Links: $20..$26
move.w d0,(a0)+
move.b d0,(a0)
lea Col38XStop(a5),a0
move.b d0,(a0)+ ;Rechts: $157..$15e
move.l d0,(a0)+
move.l d0,(a0)+
1$ bra VICIncA5
*
* Bild wird übersprungen, nur Bad-Line-Zyklen berechnen
*
VICSkip cmp.w #FirstDMALine,d7 ;Innerhalb des DMA-Bereiches?
blo VICNop
cmp.w #LastDMALine,d7
bhi VICNop
move.b d7,d0 ;Ja, stimmen die unteren Bits
and.b #7,d0 ;der Rasterzeile mit dem Y-Scroll
cmp.b YSCROLL+1(a4),d0 ;überein?
bne VICNop
move.w BadLineCycles,CyclesLeft
bra VICNop
*
* Bei 8 Bit eine Pixelzeile darstellen
* Zeiger in ChunkyBuf erhöhen
*
VICIncA5 cmp.w #STYP_8BIT,ScreenType
bne VICIncA5Really
tst.b IsCyber
beq 1$
tst.b IsCyberDirect
beq 2$
moveq #DisplayX/4-1,d0 ;CyberDirect
lea ChunkyBuf,a0
move.l CyberBase,a1
move.l a1,d1
3$ move.l (a0)+,(a1)+
dbra d0,3$
add.l CyberXMod,d1
move.l d1,CyberBase
bra VICIncRC
2$ move.l _CyberGfxBase,a6 ;Cyber
lea CyberHook,a0
move.l _the_rast_port,a1
sub.l a2,a2
jsr DoCDrawMethod(a6)
bra VICIncRC
1$ move.l _GfxBase,a6 ;Normal
move.l _the_rast_port,a0
moveq #0,d0
move.w CURRENTRASTER(a4),d1
sub.w #FirstDispLine,d1
move.l #DisplayX,d2
lea ChunkyBuf,a2
lea _temp_rp,a1
JSRLIB WritePixelLine8
bra VICIncRC
CyberHookProc move.l (a1),a0 ;a0: Adresse des Bildschirmspeichers
moveq #0,d0
move.w 20(a1),d0
move.w Registers+CURRENTRASTER,d1
sub.w #FirstDispLine,d1
mulu.w d1,d0
add.l d0,a0
lea ChunkyBuf,a1
moveq #DisplayX/4-1,d0
1$ move.l (a1)+,(a0)+
dbra d0,1$
rts
VICIncA5Really add.l #DisplayX,CURRENTA5(a4)
*
* RC erhöhen, Darstellung abschalten, wenn gleich 7
* (braucht nur im sichtbaren Bereich zu geschehen)
*
VICIncRC cmp.w #7,RC(a4)
beq 1$
addq.w #1,RC(a4)
bra 2$
1$ st.b DISPLAYOFF(a4)
move.w VCCOUNT(a4),VCBASE(a4)
2$
*
* MCs erhöhen (muß in jeder Rasterzeile geschehen, damit die Sprites
* auch im Overscan-Bereich korrekt dargestellt werden)
*
; Wenn alle Sprites aus sind, direkt zu CIA-Periodic springen
VICNop lea SPRITEON(a4),a3
move.b SPREN(a4),d0
or.b (a3),d0
beq Periodic6526
; MC für jedes Sprite zählen (7..0)
moveq #7,d6 ;d6: Spritenummer
lea M7Y(a4),a1 ;a1: Zeiger auf erste Y-Koordinate
lea MC7(a4),a2 ;a2: Zeiger auf MC
MCLoop move.b (a1),d0 ;Y-Koordinate
btst d6,SPREN(a4) ;Sprite angeschaltet?
bne 1$
3$ cmp.w #60,(a2) ;Nein, MC kleiner als 60?
blo 2$
bclr d6,(a3) ;Nein, Sprite nicht mehr darstellen
bra 5$
1$ cmp.b d0,d7 ;Sprite angeschaltet, Y-Koord. vergleichen
bne 3$
clr.w (a2) ;Gleich, MC zurücksetzen
bset d6,(a3) ;Und Sprite ab jetzt darstellen
bra 5$
2$ btst d6,MYE(a4) ;MC kleiner als 60, Sprite Y-expandiert?
beq 4$
eor.b d7,d0 ;Ja, nur erhöhen, wenn Bit 0
and.b #$01,d0 ; der Y-Koordinate gleich Bit 0
bne 5$ ; des Rasterzählers ist
4$ addq.w #3,(a2) ;MC erhöhen
subq.w #2,CyclesLeft ;2 Zyklen vom 6510 abziehen
5$ subq.w #2,a1 ;Zeiger auf Y-Koordinate erhöhen
subq.w #2,a2 ;Zeiger auf MC erhöhen
dbra d6,MCLoop
; Zu CIA-Periodic springen
bra Periodic6526
**
** Raster-IRQ auslösen
**
DoRasterIRQ lea Registers,a0
or.b #$01,IRQFLAG(a0) ;IRST-Bit setzen
btst #0,IRQMASK(a0) ;Raster-IRQ erlaubt?
beq 1$
or.b #$80,IRQFLAG(a0) ;Ja, IRQ-Bit setzen
st.b IntIsVICIRQ ;Und Interrupt auslösen
1$ rts
**
** Ein Sprite zeichnen
** d0.l: Spritedaten
** d1.w: X-Koordinate
** d2.b: Spritefarbe
** d3 : (Temp.)
** d4.b: Kollisionsergebnis Sprite-Hintergrund
** d5.b: Kollisionsergebnis Sprite-Sprite
** d6 : (Pixelzähler)
** d7.b: Sprite-Bit (1,2,4, ...)
** a1 : Ziel im Bildschirmspeicher
** a2 : Ziel im Kollisionspuffer
** a3 : Zeiger auf Grafik-Kollisionspuffer
**
CNOP 0,4
; Standard-Sprite: 3 Byte mit je 8 Pixeln konvertieren
DrawSprStd cmp.w #DisplayX-24,d1 ;Sprite horizontal sichtbar?
bhs DSSRts
moveq #0,d6 ;Pixelzähler
DSSLoop add.l d0,d0 ;Pixel gesetzt?
bcc DSSNext
IFNE SPR_DATA_COLL
tst.b (a3,d6.l) ;Ist hier schon Grafik?
beq 1$
or.b d7,d4 ;Ja, Kollision erkannt
1$
ENDC
move.b (a2,d6.l),d1 ;Ist schon ein Sprite da?
bne DSSDont
move.b d2,(a1,d6.l) ;Nein, Punkt setzen
move.b d7,(a2,d6.l)
bra DSSNext
DSSDont or.b d1,d5 ;Ja, Kollision erkannt zwischen bestehendem
or.b d7,d5 ; und aktuellem Sprite
DSSNext addq.w #1,d6
cmp.w #24,d6
bne DSSLoop
DSSRts rts
CNOP 0,4
; X-expandiertes Standard-Sprite: 3 Byte mit je 8 Pixeln konvertieren
DrawSprStdExp cmp.w #DisplayX-48,d1
bhs DSSERts
moveq #0,d6
DSSELoop add.l d0,d0
bcc DSSENext
IFNE SPR_DATA_COLL
tst.b (a3,d6.l)
beq 1$
or.b d7,d4
1$
ENDC
move.b (a2,d6.l),d1
bne DSSEDont1st
move.b d2,(a1,d6.l)
move.b d7,(a2,d6.l)
bra DSSETest2nd
DSSEDont1st or.b d1,d5
or.b d7,d5
DSSETest2nd
IFNE SPR_DATA_COLL
tst.b 1(a3,d6.l)
beq 1$
or.b d7,d4
1$
ENDC
move.b 1(a2,d6.l),d1
bne DSSEDont2nd
move.b d2,1(a1,d6.l)
move.b d7,1(a2,d6.l)
bra DSSENext
DSSEDont2nd or.b d1,d5
or.b d7,d5
DSSENext addq.w #2,d6
cmp.w #48,d6
bne DSSELoop
DSSERts rts
CNOP 0,4
; Multicolor-Sprite: 3 Byte mit je 4 Pixeln konvertieren
DrawSprMulti cmp.w #DisplayX-24,d1
bhs DSMRts
moveq #0,d6
DSMLoop add.l d0,d0 ;Farbe des Pixels bestimmen
bcc DSMFirstIs0
add.l d0,d0
bcc DSMDraw10
move.b $26(a4),d3 ;11
bra DSMDraw
DSMDraw10 move.b d2,d3 ;10
bra DSMDraw
DSMFirstIs0 add.l d0,d0
bcc DSMNext
move.b $25(a4),d3 ;01
DSMDraw
IFNE SPR_DATA_COLL
tst.b (a3,d6.l)
beq 1$
or.b d7,d4
1$
ENDC
move.b (a2,d6.l),d1
bne DSMDont1st
move.b d3,(a1,d6.l)
move.b d7,(a2,d6.l)
bra DSMTest2nd
DSMDont1st or.b d1,d5
or.b d7,d5
DSMTest2nd
IFNE SPR_DATA_COLL
tst.b 1(a3,d6.l)
beq 1$
or.b d7,d4
1$
ENDC
move.b 1(a2,d6.l),d1
bne DSMDont2nd
move.b d3,1(a1,d6.l)
move.b d7,1(a2,d6.l)
bra DSMNext
DSMDont2nd or.b d1,d5
or.b d7,d5
DSMNext addq.w #2,d6
cmp.w #24,d6
bne DSMLoop
DSMRts rts
CNOP 0,4
; X-expandiertes Multicolor-Sprite: 3 Byte mit je 4 Pixeln konvertieren
DrawSprMultiExp cmp.w #DisplayX-48,d1
bhs DSMERts
moveq #0,d6
DSMELoop add.l d0,d0
bcc DSMEFirstIs0
add.l d0,d0
bcc DSMEDraw10
move.b $26(a4),d3 ;11
bra DSMEDraw
DSMEDraw10 move.b d2,d3 ;10
bra DSMEDraw
DSMEFirstIs0 add.l d0,d0
bcc DSMENext
move.b $25(a4),d3 ;01
DSMEDraw
IFNE SPR_DATA_COLL
tst.b (a3,d6.l)
beq 1$
or.b d7,d4
1$
ENDC
move.b (a2,d6.l),d1
bne DSMEDont1st
move.b d3,(a1,d6.l)
move.b d7,(a2,d6.l)
bra DSMETest2nd
DSMEDont1st or.b d1,d5
or.b d7,d5
DSMETest2nd
IFNE SPR_DATA_COLL
tst.b 1(a3,d6.l)
beq 1$
or.b d7,d4
1$
ENDC
move.b 1(a2,d6.l),d1
bne DSMEDont2nd
move.b d3,1(a1,d6.l)
move.b d7,1(a2,d6.l)
bra DSMETest3rd
DSMEDont2nd or.b d1,d5
or.b d7,d5
DSMETest3rd
IFNE SPR_DATA_COLL
tst.b 2(a3,d6.l)
beq 1$
or.b d7,d4
1$
ENDC
move.b 2(a2,d6.l),d1
bne DSMEDont3rd
move.b d3,2(a1,d6.l)
move.b d7,2(a2,d6.l)
bra DSMETest4th
DSMEDont3rd or.b d1,d5
or.b d7,d5
DSMETest4th
IFNE SPR_DATA_COLL
tst.b 3(a3,d6.l)
beq 1$
or.b d7,d4
1$
ENDC
move.b 3(a2,d6.l),d1
bne DSMEDont4th
move.b d3,3(a1,d6.l)
move.b d7,3(a2,d6.l)
bra DSMENext
DSMEDont4th or.b d1,d5
or.b d7,d5
DSMENext addq.w #4,d6
cmp.w #48,d6
bne DSMELoop
DSMERts rts
CNOP 0,4
; Standard-Sprite im Hintergrund: 3 Byte mit je 8 Pixeln konvertieren
DrawBackStd cmp.w #DisplayX-24,d1 ;Sprite horizontal sichtbar?
bhs DBSRts
moveq #0,d6 ;Pixelzähler
DBSLoop add.l d0,d0 ;Pixel gesetzt?
bcc DBSNext
IFNE SPR_DATA_COLL
tst.b (a3,d6.l) ;Ist hier schon Grafik?
beq 1$
or.b d7,d4 ;Ja, Kollision erkannt
move.b (a2,d6.l),d1 ;Ist schon ein Sprite da?
beq DBSNext
or.b d1,d5 ;Ja, Kollision erkannt
or.b d7,d5
bra DBSNext ;Sprite nicht zeichnen
1$
ENDC
move.b (a2,d6.l),d1 ;Ja, ist schon ein Sprite da?
bne DBSDont
move.b d2,(a1,d6.l) ;Nein, Punkt setzen
move.b d7,(a2,d6.l)
bra DBSNext
DBSDont or.b d1,d5 ;Ja, Kollision erkannt zwischen bestehendem
or.b d7,d5 ; und aktuellem Sprite
DBSNext addq.w #1,d6
cmp.w #24,d6
bne DBSLoop
DBSRts rts
CNOP 0,4
; X-expandiertes Standard-Sprite im Hintergrund: 3 Byte mit je 8 Pixeln konvertieren
DrawBackStdExp cmp.w #DisplayX-48,d1
bhs DBSERts
moveq #0,d6
DBSELoop add.l d0,d0
bcc DBSENext
IFNE SPR_DATA_COLL
tst.b (a3,d6.l)
beq 1$
or.b d7,d4
move.b (a2,d6.l),d1
beq DBSETest2nd
or.b d1,d5
or.b d7,d5
bra DBSETest2nd
1$
ENDC
move.b (a2,d6.l),d1
bne DBSEDont1st
move.b d2,(a1,d6.l)
move.b d7,(a2,d6.l)
bra DBSETest2nd
DBSEDont1st or.b d1,d5
or.b d7,d5
DBSETest2nd
IFNE SPR_DATA_COLL
tst.b 1(a3,d6.l)
beq 1$
or.b d7,d4
move.b 1(a2,d6.l),d1
beq DBSENext
or.b d1,d5
or.b d7,d5
bra DBSENext
1$
ENDC
move.b 1(a2,d6.l),d1
bne DBSEDont2nd
move.b d2,1(a1,d6.l)
move.b d7,1(a2,d6.l)
bra DBSENext
DBSEDont2nd or.b d1,d5
or.b d7,d5
DBSENext addq.w #2,d6
cmp.w #48,d6
bne DBSELoop
DBSERts rts
CNOP 0,4
; Multicolor-Sprite im Hintergrund: 3 Byte mit je 4 Pixeln konvertieren
DrawBackMulti cmp.w #DisplayX-24,d1
bhs DBMRts
moveq #0,d6
DBMLoop add.l d0,d0 ;Farbe des Pixels bestimmen
bcc DBMFirstIs0
add.l d0,d0
bcc DBMDraw10
move.b $26(a4),d3 ;11
bra DBMDraw
DBMDraw10 move.b d2,d3 ;10
bra DBMDraw
DBMFirstIs0 add.l d0,d0
bcc DBMNext
move.b $25(a4),d3 ;01
DBMDraw
IFNE SPR_DATA_COLL
tst.b (a3,d6.l)
beq 1$
or.b d7,d4
move.b (a2,d6.l),d1
beq DBMTest2nd
or.b d1,d5
or.b d7,d5
bra DBMTest2nd
1$
ENDC
move.b (a2,d6.l),d1
bne DBMDont1st
move.b d3,(a1,d6.l)
move.b d7,(a2,d6.l)
bra DBMTest2nd
DBMDont1st or.b d1,d5
or.b d7,d5
DBMTest2nd
IFNE SPR_DATA_COLL
tst.b 1(a3,d6.l)
beq 1$
or.b d7,d4
move.b 1(a2,d6.l),d1
beq DBMNext
or.b d1,d5
or.b d7,d5
bra DBMNext
1$
ENDC
move.b 1(a2,d6.l),d1
bne DBMDont2nd
move.b d3,1(a1,d6.l)
move.b d7,1(a2,d6.l)
bra DBMNext
DBMDont2nd or.b d1,d5
or.b d7,d5
DBMNext addq.w #2,d6
cmp.w #24,d6
bne DBMLoop
DBMRts rts
CNOP 0,4
; X-expandiertes Multicolor-Sprite im Hintergrund: 3 Byte mit je 4 Pixeln konvertieren
DrawBackMultiExp cmp.w #DisplayX-48,d1
bhs DBMERts
moveq #0,d6
DBMELoop add.l d0,d0
bcc DBMEFirstIs0
add.l d0,d0
bcc DBMEDraw10
move.b $26(a4),d3 ;11
bra DBMEDraw
DBMEDraw10 move.b d2,d3 ;10
bra DBMEDraw
DBMEFirstIs0 add.l d0,d0
bcc DBMENext
move.b $25(a4),d3 ;01
DBMEDraw
IFNE SPR_DATA_COLL
tst.b (a3,d6.l)
beq 1$
or.b d7,d4
move.b (a2,d6.l),d1
beq DBMETest2nd
or.b d1,d5
or.b d7,d5
bra DBMETest2nd
1$
ENDC
move.b (a2,d6.l),d1
bne DBMEDont1st
move.b d3,(a1,d6.l)
move.b d7,(a2,d6.l)
bra DBMETest2nd
DBMEDont1st or.b d1,d5
or.b d7,d5
DBMETest2nd
IFNE SPR_DATA_COLL
tst.b 1(a3,d6.l)
beq 1$
or.b d7,d4
move.b 1(a2,d6.l),d1
beq DBMETest3rd
or.b d1,d5
or.b d7,d5
bra DBMETest3rd
1$
ENDC
move.b 1(a2,d6.l),d1
bne DBMEDont2nd
move.b d3,1(a1,d6.l)
move.b d7,1(a2,d6.l)
bra DBMETest3rd
DBMEDont2nd or.b d1,d5
or.b d7,d5
DBMETest3rd
IFNE SPR_DATA_COLL
tst.b 2(a3,d6.l)
beq 1$
or.b d7,d4
move.b 2(a2,d6.l),d1
beq DBMETest4th
or.b d1,d5
or.b d7,d5
bra DBMETest4th
1$
ENDC
move.b 2(a2,d6.l),d1
bne DBMEDont3rd
move.b d3,2(a1,d6.l)
move.b d7,2(a2,d6.l)
bra DBMETest4th
DBMEDont3rd or.b d1,d5
or.b d7,d5
DBMETest4th
IFNE SPR_DATA_COLL
tst.b 3(a3,d6.l)
beq 1$
or.b d7,d4
move.b 3(a2,d6.l),d1
beq DBMENext
or.b d1,d5
or.b d7,d5
bra DBMENext
1$
ENDC
move.b 3(a2,d6.l),d1
bne DBMEDont4th
move.b d3,3(a1,d6.l)
move.b d7,3(a2,d6.l)
bra DBMENext
DBMEDont4th or.b d1,d5
or.b d7,d5
DBMENext addq.w #4,d6
cmp.w #48,d6
bne DBMELoop
DBMERts rts
**
** Amiga-Mono-Routinen einbinden
**
INCLUDE "6569mono.i"
**
** Konstanten
**
; Tabelle der Display-Routinen (jeweils für Farbe und Monochrom)
CNOP 0,4
DispProcTab dc.l TextStd
dc.l TextMulti
dc.l BitMapStd
dc.l BitMapMulti
dc.l TextECM
dc.l BlackScreen
dc.l BlackScreen
dc.l BlackScreen
MonoDispProcTab dc.l FTextStd
dc.l FTextStd
dc.l FBitMapStd
dc.l FBitMapStd
dc.l FTextStd
dc.l FBlackScreen
dc.l FBlackScreen
dc.l FBlackScreen
; Tabelle der Sprite-Display-Routinen
SpriteProcTab dc.l DrawSprStd
dc.l DrawSprStdExp
dc.l DrawSprMulti
dc.l DrawSprMultiExp
dc.l DrawBackStd
dc.l DrawBackStdExp
dc.l DrawBackMulti
dc.l DrawBackMultiExp
; Hook für DoCDrawMethod
CyberHook dc.l 0,0
dc.l CyberHookProc
dc.l 0
dc.l 0
**
** Datenbereich
**
; Variablen
CNOP 0,4
DisplayProc dc.l 0 ;Zeiger auf die Display-Routine (Text/Bitmap etc.)
Sprite0Proc dc.l 0 ;Zeiger auf Display-Routinen für die einzelnen Sprites
Sprite1Proc dc.l 0
Sprite2Proc dc.l 0
Sprite3Proc dc.l 0
Sprite4Proc dc.l 0
Sprite5Proc dc.l 0
Sprite6Proc dc.l 0
Sprite7Proc dc.l 0
DisplayID dc.l 0 ;Prefs: DisplayID des Screens
ScreenType dc.w 0 ;Prefs: Typ der Screen-Ansteuerung
NormalCycles dc.w 0 ;Prefs: Anzahl 6510-Zyklen pro Rasterzeile
BadLineCycles dc.w 0 ;Prefs: Anzahl 6510-Zyklen in einer Bad Line
SpritesOn dc.w 0 ;Prefs: Sprites-Darstellung angeschaltet
Collisions dc.w 0 ;Prefs: Sprite-Kollisionen angeschaltet
Overscan dc.w 0 ;Prefs: Overscan-Typ für Amiga-Modi
DirectVideo dc.w 0 ;Prefs: Direkter Grafikspeicherzugriff bei 8 Bit erlaubt
SkipCounter dc.w 1
XDEF _SkipLatch
_SkipLatch
SkipLatch dc.w 0 ;Prefs: Nur jedes nte Bild darstellen
XDEF _LimitSpeed
_LimitSpeed
LimitSpeed dc.w 0 ;Prefs: Geschwindigkeit auf 100% beschränken
IsCyber dc.b 0 ;#0: DoCDrawMethod kann statt WritePixelLine8 benutzt werden
IsCyberDirect dc.b 0 ;#0: Direkter Bildschirmspeicherzugriff erlaubt
CNOP 0,4
CyberBase dc.l 0 ;Basisadresse des Bildschirmspeichers
CyberXMod dc.l 0 ;Modulo des Bildschirmspeichers
CNOP 0,4
Registers ds.b VICRegLength ;VIC-Register
MatrixLine ds.b 40 ;Eine Bildschirmzeile
ColorLine ds.b 40 ;Eine Farb-RAM-Zeile
**
** Nicht initialisierte Daten
**
SECTION "BSS",BSS
XDEF _ChunkyBuf
_ChunkyBuf
ChunkyBuf ds.b DisplayX*DisplayY ;Puffer für die Chunky-Bitmap
SprCollBuf ds.b DisplayX ;Puffer für Sprite-Sprite-Kollisionen
IFNE SPR_DATA_COLL
GfxCollBuf ds.b DisplayX ;Puffer für Sprite-Grafik-Kollisionen und Priorität
ENDC
XDEF _CURRENTA5
_CURRENTA5 ds.l 1 ;Kommunikation mit _RedrawDisplay
END